﻿using System;
using System.IO;
using System.Xml;
using NetActive.Notifications.Services.WP7.Interfaces;

namespace NetActive.Notifications.Services.WP7
{
    public class ToastNotification : NotificationBase
    {
        /// <summary>
        /// Constructor for <seealso cref="ToastNotification"/> with just a title.
        /// </summary>
        /// <param name="clientNotificationChannelUri">Client notification channel Uri.</param>
        /// <param name="title">Toast notification title.</param>
        public ToastNotification(Uri clientNotificationChannelUri, string title)
            : base(clientNotificationChannelUri)
        {
            ClientNotificationChannelUri = clientNotificationChannelUri;
            Title = title;
        }

        /// <summary>
        /// Constructor for <seealso cref="ToastNotification"/> with a title and a message.
        /// </summary>
        /// <param name="clientNotificationChannelUri">Client notification channel Uri.</param>
        /// <param name="title">Toast notification title.</param>
        /// <param name="message">Toast notification message (or sub title).</param>
        public ToastNotification(Uri clientNotificationChannelUri, string title, string message)
            : this(clientNotificationChannelUri, title)
        {
            Message = message;
        }

        /// <summary>
        /// Gets or sets the title of the toast notification.
        /// </summary>
        public string Title { get; set; }

        /// <summary>
        /// Gets or sets the message (or sub title) of the toast notification.
        /// </summary>
        public string Message { get; set; }

        /// <summary>
        /// Gets or sets the Uri to navigate to within the end user application.
        /// </summary>
        public string NavUri { get; set; }

        /// <summary>
        /// Gets the string representing the target header for this notification type.
        /// </summary>
        public override string TargetHeader
        {
            get { return "toast"; }
        }

        /// <summary>
        /// Method used to return a byte representation of the notification ready to send to the Push Notification Services.
        /// </summary>
        /// <returns>Byte representation of the notification.</returns>
        public override byte[] GetBytes()
        {
            using (var stream = new MemoryStream())
            {
                var settings = GetSettings();

                using (var writer = XmlWriter.Create(stream, settings))
                {
                    writer.WriteStartDocument();
                    writer.WriteStartElement("wp", "Notification", "WPNotification");
                    writer.WriteStartElement("wp", "Toast", "WPNotification");
                    
                    writer.WriteStartElement("wp", "Text1", "WPNotification");
                    writer.WriteValue(Title);
                    writer.WriteEndElement();
                    
                    writer.WriteStartElement("wp", "Text2", "WPNotification");
                    writer.WriteValue(Message);
                    writer.WriteEndElement();
                    
                    writer.WriteStartElement("wp", "Param", "WPNotification");
                    writer.WriteValue(NavUri);
                    writer.WriteEndElement();
                    
                    writer.WriteEndElement();
                    writer.WriteEndDocument();
                    writer.Close();

                    var payload = stream.ToArray();

                    return payload;
                }
            }
        }

        /// <summary>
        /// Returns and integer value representing the selected <seealso cref="INotification.DeliveryInterval"/>.
        /// </summary>
        /// <returns>Integer value representing the delivery interval.</returns>
        public override int GetDeliveryInterval()
        {
            if (DeliveryInterval == NotificationDeliveryInterval.Within450Seconds) return 12;
            return DeliveryInterval == NotificationDeliveryInterval.Within900Seconds ? 22 : 2;
        }
    }
}